
package com.scalar.chiptrack.operations.boards.actions;

import java.util.Date;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import java.util.ArrayList;
import java.util.StringTokenizer;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.util.LabelValueBean;

import com.scalar.ScalarException;
import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.operations.boards.forms.BoardInventoryDataEntryForm;
import com.scalar.chiptrack.operations.process.dao.LotDAO;
import com.scalar.chiptrack.operations.process.dao.ProductDao;
import com.scalar.chiptrack.operations.vendor.dao.VendorDAO;
import com.scalar.chiptrack.operations.process.VendorLocation;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.commons.Constants;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.operations.process.dao.PartNumber;
import com.scalar.chiptrack.operations.process.ProcessStep;
import com.scalar.chiptrack.operations.process.Lot;
//import com.scalar.chiptrack.operations.process.dao.PartNumber;
//import com.scalar.chiptrack.commons.Location;



public final class BoardInventoryDataEntryAction extends ChipTrackAction
{

    public BoardInventoryDataEntryAction()
	{
    }

    public ActionForward execute (ActionMapping mapping, ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response) throws Exception
	{
		ArrayList partNumberList = new ArrayList();
		ProductDao productDao    = new ProductDao();
		BoardInventoryDataEntryForm inventoryDataEntryForm = ( BoardInventoryDataEntryForm ) form;
		HttpSession ses = request.getSession(true);

		String action = request.getParameter("action");
		if(action==null || action.equals("submit"))
		action="";
		request.setAttribute("action",action);

		String commingFrom = (String)request.getAttribute("comingFrom");
		if(commingFrom==null)
		{
			commingFrom ="";
		}


		if(!commingFrom.equals(""))
		{
			inventoryDataEntryForm	= (BoardInventoryDataEntryForm)ses.getAttribute("inventoryDataEntryForm");
			String lot = inventoryDataEntryForm.getLotNo();
			StringTokenizer st1 = new StringTokenizer(lot,"$");
			String lotId			= st1.nextToken();
			String lotNumber        = st1.nextToken();
			LotDAO lotDao = new LotDAO();
			String commingLot = LotDAO.putLotInNextStep(null,lotId,lotNumber);
			StringTokenizer st		= new StringTokenizer(commingLot,"##");
			String errorCode		= st.nextToken();
			String commingLotId			= st.nextToken();
			inventoryDataEntryForm.setLotNo(commingLotId+"$"+lotNumber+"$"+"Running");
			request.setAttribute("boardInventorydataentryform",inventoryDataEntryForm);
			ses.removeAttribute("boardInventoryDataEntryForm");
		}

		int prevProcessStepId=0;
		String prevLotId="";

		//partNumberList = productDao.getInventoryPartNumber(inventoryDataEntryForm.getType());
		partNumberList = productDao.getBoardPartNumber();
		PartNumber partNumber = null;
		ArrayList partNumberSelectList = new ArrayList();

		for ( int i=0;i<partNumberList.size();i++ )
		{
			partNumber = (PartNumber)partNumberList.get(i);
			partNumberSelectList.add(new LabelValueBean(partNumber.getPartNumber(), partNumber.getProcessStepId()));
		}

		request.setAttribute("partNumberSelectList",partNumberSelectList);

		if(action.equals("type"))
		{
			return (mapping.findForward("success"));
		}

		LotDAO lotDao = null;

		if(action.equals("location") || action.equals("partnumber") || action.equals("lotnumber") || action.equals("save") || !commingFrom.equals("") )
		{
			int procStepId = Integer.parseInt(inventoryDataEntryForm.getProcessStepId());
			ArrayList inventoryLocationList= VendorDAO.getSelectedLocations ( procStepId );
			ArrayList vendorLocationList = new ArrayList();
			ArrayList lotList = new ArrayList();
			ArrayList lotNumberList =new ArrayList();
			lotDao = new LotDAO();
			VendorLocation vendorLocation = null;
			if(inventoryLocationList == null)
			{
				inventoryLocationList = new ArrayList(0);
			}
			for(int i=0;i<inventoryLocationList.size();i++)
			{
				vendorLocation = ( VendorLocation ) inventoryLocationList.get ( i );
				vendorLocation.setLocationID ( vendorLocation.getLocationID () );
				vendorLocation.setLocationName ( vendorLocation.getLocationName () );
				vendorLocationList.add ( new LabelValueBean ( vendorLocation.getLocationName (),new Integer ( vendorLocation.getLocationID () ).toString () ) );
			}
			//system.out.println("PSId = "+inventoryDataEntryForm.getProcessStepId());
			//system.out.println("Vendor Loc "+vendorLocation.getLocationID());
			//lotNumberList = lotDao.getAllLotNumbers(inventoryDataEntryForm.getProcessStepId(), vendorLocation.getLocationID());
			//Lot lot = null;
			//if(lotNumberList == null)
			//{
				//lotNumberList = new ArrayList();
			//}
			//for(int j=0;j<lotNumberList.size();j++)
			//{
				//lot =(Lot)lotNumberList.get(j);
				//lotList.add(new LabelValueBean(lot.getLotNumber(),lot.getLotId()+"$"+lot.getLotNumber()+"$"+lot.getStatus()));
			//}
			//}
			request.setAttribute("locationSelectList",vendorLocationList);
			request.setAttribute("showLotNumbers","FALSE");
		}



		if(action.equals("location") || action.equals("lotnumber") || action.equals("save") || !commingFrom.equals("")  )
		{
			ArrayList lotNumberList = LotDAO.getAllLotNumbers(inventoryDataEntryForm.getProcessStepId(),inventoryDataEntryForm.getLocationId());
			Lot lot = null;
			java.util.ArrayList list = new java.util.ArrayList();

			if(lotNumberList == null)
			{
				lotNumberList = new ArrayList(0);
			}

			for(int i=0;i<lotNumberList.size();i++)
			{
				//system.out.println("NULL");
				lot =(Lot)lotNumberList.get(i);
				list.add(new LabelValueBean(lot.getLotNumber(),lot.getLotId()+"$"+lot.getLotNumber()+"$"+lot.getStatus()));
			}

			request.setAttribute("lotNumbers",list);
			request.setAttribute("showLotNumbers","TRUE");
			if ( action.equals ( "location" ) )
			{
				inventoryDataEntryForm.setLotNo("0");
				return (mapping.findForward("success"));
			}

			if(!commingFrom.equals("")){
				return (mapping.findForward("success"));
			}
		}

		if (action.equals ( "partnumber" ) )
		{
			inventoryDataEntryForm.setLotNo("0");
			inventoryDataEntryForm.setLocationId("0");
		}

		if (action.equals("lotnumber"))
		{
			String lot = inventoryDataEntryForm.getLotNo();
			// For BOARD
			// Added by Balaram, Feb 26, 2003
			if ("-1".equalsIgnoreCase(lot) == true)
			{// Create a New Lot
				request.setAttribute ("isNewLot", "true");
				request.setAttribute("InsertingDateIn", StringUtils.formatDateToString(new Date(System.currentTimeMillis()), "MM/dd/yyyy"));
				request.setAttribute("boardInventorydataentryform",inventoryDataEntryForm);
				return (mapping.findForward ("success"));
			}

			StringTokenizer st = new StringTokenizer(lot,"$");
			String lotId = st.nextToken();
			String lotNumber = st.nextToken();
			String status = st.nextToken();
			if(status.equals ("Ongoing"))
			{
				request.setAttribute("lotId",lotId);
				request.setAttribute("returnPage","/boardInventoryDataEntry.do");
				ses.setAttribute("boardInventoryDataEntryForm",inventoryDataEntryForm);
				return (mapping.findForward ("lotShippingInstructions"));
			}

			BoardInventoryDataEntryForm inventoryLot = LotDAO.getBoardInventoryLotData (lotId);
			//system.out.println("This is check");
			String dateIn       = inventoryLot.getDateIn();
			String qtyIn        = inventoryLot.getQuantityIn();
			String testQty      = inventoryLot.getTestQuantity();
			String rejectedQty  = inventoryLot.getRejectedQty();
            String dateCode     = inventoryLot.getDateCode();
            //system.out.println("Lot No "+lotNumber);

			request.setAttribute("InsertingNewLotNumber", lotNumber);
			request.setAttribute("InsertingDateIn", dateIn);
			request.setAttribute("InsertingQuantityIn", testQty);
			request.setAttribute("testedQuantity", qtyIn);
			request.setAttribute("rejectedQuantity", rejectedQty);
            request.setAttribute("dateCode", dateCode );
			request.setAttribute( "boardInventorydataentryform", inventoryDataEntryForm );
			return (mapping.findForward ("success"));
		}
		if(action.equals("save"))
		{
			HashMap errors = new HashMap();
			HashMap info = new HashMap();

			request.setAttribute (SessionKeys.ERROR_MESSAGES, errors);
			request.setAttribute (SessionKeys.INFO_MESSAGES, info);

			String processStepId = inventoryDataEntryForm.getProcessStepId();
			int pStepId = 0;
			try
			{
				pStepId = Integer.parseInt ( processStepId );
			}
			catch ( NumberFormatException e )
			{
				System.out.println ( "--exception while parsing processStepId--" );
			}

			String partNo                   =  ProductDao.getProductNameByProcessStep_Id ( pStepId );
			String[] insertingDateIn        = inventoryDataEntryForm.getInsertingDateIn();
			String[] insertingQuantityIn    = inventoryDataEntryForm.getInsertingQuantityIn();
			String locationId               = inventoryDataEntryForm.getLocationId();
			String[] newLotNumber           = inventoryDataEntryForm.getNewLotNumber();
			String[] testedQuantity         = inventoryDataEntryForm.getTestedQuantity();
			String[] rejectedQuantity       = inventoryDataEntryForm.getRejectedQuantity();
            String[] dateCodes              = inventoryDataEntryForm.getDateCodes();

			// For BOARD
			// Added by Balaram, Feb 26, 2003
			String lotString = inventoryDataEntryForm.getLotNo();
			if ("-1".equalsIgnoreCase(lotString) == true)
			{   // Create a New Lot
				try
				{
					//Bhaskar on 27 sep 2003 added the if conditon below.
					//This will check whether the same lot number already exists
					//in the lot_table or not
					ArrayList lotNums = LotDAO.getInventoryLotNumbers ( newLotNumber, processStepId, locationId );
					if ( !lotNums.isEmpty() )
					{
						for (int count = 0; count < lotNums.size(); count++ )
						{
							//system.out.println ("Lot Number "+lotNums.get (count)+" already present Please enter another lot number");
							errors.put ("Lot Number "+lotNums.get (count)+" already present Please enter another lot number", null);
						}
						throw new ScalarException("Same Lot Number already present");
					}
					//LotDAO.createInventoryLot (null, processStepId, locationId, newLotNumber, quantityIn, quantityOut, dateIn, dateOut);
					LotDAO.createInventoryLot (null, processStepId, locationId, newLotNumber, insertingQuantityIn, insertingDateIn, testedQuantity, rejectedQuantity, dateCodes );
					/*for(int i=0;i<newLotNumber.length;i++)
					{
						if ( newLotNumber[i].trim().length() == 0 )
							continue;
						info.put ("Lot has been successfully created for " + newLotNumber[i], null);
					}*/
					info.put ("Lot(s) have been successfully created for " + partNo, null);
				}
				catch (ScalarException se)
				{
					if ( !se.getMessage().equals("Same Lot Number already present" ) )
						errors.put ("Internal Server Error", "Could not create Inventory Lot");
					request.setAttribute("showData", "TRUE");

				}

				try
				{
					ArrayList lotNumberList = LotDAO.getAllLotNumbers(inventoryDataEntryForm.getProcessStepId(),inventoryDataEntryForm.getLocationId());
					if ( lotNumberList == null )
					{
						lotNumberList = new ArrayList();
					}
					ArrayList list = new java.util.ArrayList();
					Lot lot = null;
					for ( int i=0;i<lotNumberList.size();i++ )
					{
						lot =(Lot)lotNumberList.get(i);
						list.add(new LabelValueBean(lot.getLotNumber(),lot.getLotId()+"$"+lot.getLotNumber()+"$"+lot.getStatus()));
					}
					request.setAttribute ("lotNumbers",list);
				}
				catch (ScalarException se)
				{
					errors.put ("Internal Server Error", "Please contact System Administrator");
					//se.printStackTrace();
				}
				catch (Exception se)
				{
					errors.put ("Internal Server Error", "Please contact System Administrator");
					//se.printStackTrace();
				}
				request.setAttribute("InsertingDateIn", StringUtils.formatDateToString(new Date(System.currentTimeMillis()), "MM/dd/yyyy"));
				request.setAttribute("InsertingQuantityIn", "");
				request.setAttribute("InsertingNewLotNumber","");

				request.setAttribute("isNewLot","true");
				/*inventoryDataEntryForm.setInsertingDateIn(insertingDateIn);
				inventoryDataEntryForm.setInsertingQuantityIn(insertingQuantityIn);
				inventoryDataEntryForm.setNewLotNumber(newLotNumber);
				request.setAttribute("repeatData",inventoryDataEntryForm);*/
				request.setAttribute("boardInventorydataentryform",inventoryDataEntryForm);
			}
			else
			{
				StringTokenizer st = new StringTokenizer(lotString,"$");
				String lotId = st.nextToken();
				String[] updatingLotId = {lotId};
				String lotNumber = st.nextToken();

				String[] temp = inventoryDataEntryForm.getNewLotNumber();
				String[] updatingNewLotNumber = {temp[0]};
				String type = ProcessStep.getProcessType(Integer.parseInt(processStepId));

				lotDao = new LotDAO();

				//String[] updatingLot = inventoryDataEntryForm.getInsertingLotId();
				String[] updatingDateIn= inventoryDataEntryForm.getInsertingDateIn();
				String[] updatingQuantityIn = inventoryDataEntryForm.getInsertingQuantityIn();
				//String[] testedQuantity = inventoryDataEntryForm.getTestedQuantity();

				request.setAttribute("InsertingNewLotNumber",updatingNewLotNumber[0]);
				request.setAttribute("InsertingDateIn", updatingDateIn[0]);
				request.setAttribute("InsertingQuantityIn", updatingQuantityIn[0]);
				request.setAttribute("testedQuantity", testedQuantity[0]);
				request.setAttribute("rejectedQuantity", rejectedQuantity[0]);
                request.setAttribute("dateCode", dateCodes[0]);
				request.setAttribute("boardInventorydataentryform",inventoryDataEntryForm);
				DBTransaction dbTransaction = null;
				boolean success = false;
				dbTransaction = DBTransaction.getInstance();
				dbTransaction.begin();
				try {
					//Bhaskar on 27 sep 2003 added the if conditon below.
					//This will check whether the same lot number already exists
					//in the lot_table or not
					if ( ! lotNumber.equalsIgnoreCase ( updatingNewLotNumber[0] ) )
					{
						ArrayList lotNums = LotDAO.getInventoryLotNumbers ( updatingNewLotNumber, processStepId, locationId );
						if ( !lotNums.isEmpty() )
						{
							for (int count = 0; count < lotNums.size(); count++ )
							{
								errors.put ("Lot Number "+lotNums.get (count)+" already present Please enter another lot number", null);
							}
							throw new ScalarException("Same Lot Number already present");
						}
					}
					//Step1 : Save Inventory Lot
					//lotDao.saveInventoryLot(dbTransaction,lotId,dateIn,dateOut,quantityIn,quantityOut);
                    int qtyPulled = LotDAO.getCSLNTQuantityPulled (dbTransaction, lotId );
                    int qtyIn = 0;
                    try{
                        qtyIn = Integer.parseInt( testedQuantity[0] );
                    }
                    catch(Exception e){}
                    if( qtyIn < qtyPulled )
                    {
                        errors.put ( "Lot Good Qunatity cannot be less than the Issued Quantity in PackingSlip:"+ qtyPulled , null);
                        throw new ScalarException( "Good Qty cannot be less than the Qty Pulled" );
                    }

                    int shippedQty = LotDAO.getCSLNTQuantityShippedByLotId( dbTransaction, lotId );
                    int rejectedQty = 0;
                    try
                    {
                        rejectedQty = Integer.parseInt ( rejectedQuantity[0] );
                    } catch ( NumberFormatException ignore ){}
                    int goodQty = 0;
                    try
                    {
                        goodQty = Integer.parseInt ( testedQuantity[0] );
                    } catch ( NumberFormatException ignore ){}
                    int unTestedQty = 0;
                    try
                    {
                        unTestedQty = Integer.parseInt ( updatingQuantityIn[0] );
                    } catch( NumberFormatException ignore ) {}
                    if ( unTestedQty < ( shippedQty + rejectedQty + goodQty ) )
                    {
                        errors.put ( "Un Tested Qty can not be less than ( Shipped Qty+Good Qty+Rejected Qty )",null);
                        errors.put ( "Packing Slip Shipped Qty:" + shippedQty, null );
                        throw new ScalarException ( "Un Tested Qty is less than the total Qty" );
                    }
                    LotDAO.saveInventoryLot(dbTransaction,updatingNewLotNumber,updatingLotId,updatingDateIn,updatingQuantityIn, testedQuantity, rejectedQuantity, dateCodes );
					//info.put ("Lot has been successfully updated for " + updatingNewLotNumber[0], null);
					info.put ("Lot has been successfully updated for " + partNo, null);
                    String lotStatus = LotDAO.getLotStatus( dbTransaction, updatingLotId[0]);
                    if ( Constants.LOT_STATUS_CLOSED.equalsIgnoreCase( lotStatus ) )
                    {
                        //lot is closed
                        //info.put ( "Lot has been Closed since all the lot qty is issued", null );
                        request.setAttribute("InsertingNewLotNumber","");
                        request.setAttribute("InsertingDateIn", updatingDateIn[0]);
                        request.setAttribute("InsertingQuantityIn", "");
                        request.setAttribute("testedQuantity", "");
                        request.setAttribute("rejectedQuantity", "");
                        request.setAttribute("dateCode", "");
                    }
					//Step2 : Update Lot Status
					/*if(quantityOut!=null && dateOut!=null){
						lotDao.updateLotStatus(dbTransaction,Integer.parseInt(lotId));

						Step 3 : Put Lot in next step,If Lot Shipping instructions present
						lotDao.putLotInNextStep(dbTransaction,lotId,lotNumber);
					}*/
					success = true;
				}
				catch (ScalarException se)
				{
					if ( !se.getMessage().equals("Same Lot Number already present" ) && !se.getMessage().equals("Good Qty cannot be less than the Qty Pulled" ) && !se.getMessage().equalsIgnoreCase( "Un Tested Qty is less than the total Qty" ) )
						errors.put ("Internal Server Error", "Could not create Inventory Lot");
				}
				finally
				{
					try
					{
						if(success==true)
						{
							if (dbTransaction != null)
							{
								dbTransaction.commit();
								ArrayList arr = getLotNumbers ( inventoryDataEntryForm , lotDao );
								request.setAttribute ( "lotNumbers", arr );
								String newlotid = getLotId(updatingLotId[0], updatingNewLotNumber[0], lotString ) ;
								inventoryDataEntryForm.setLotNo ( newlotid );
							}
						}
						else
						{
							if (dbTransaction != null)
							{
								dbTransaction.rollback();
							}
						}
					}
					catch (Exception e1)
					{
						errors.put ("Internal Server Error", "Please contact System Administrator");
						//e1.printStackTrace();
					}
				}
			}   //else
		}
		return (mapping.findForward("success"));
	}


	private ArrayList getLotNumbers(BoardInventoryDataEntryForm forms, LotDAO lotDao)
	{
		java.util.ArrayList list = new java.util.ArrayList();
		try
		{
			ArrayList lotNumberList = LotDAO.getAllLotNumbers(forms.getProcessStepId(),forms.getLocationId());
			Lot lot = null;
			if(lotNumberList == null)
			{
				lotNumberList = new ArrayList();
			}
			for(int i=0;i<lotNumberList.size();i++)
			{
				lot =(Lot)lotNumberList.get(i);
				list.add(new LabelValueBean(lot.getLotNumber(),lot.getLotId()+"$"+lot.getLotNumber()+"$"+lot.getStatus()));
			}
		}
		catch(Exception e)
		{

		}
		return list;
	}


	private String getLotId(String updatedLotId, String updatedNewLotNumber, String lotString )
	{
		String newLotId = "";
		String newId = lotString.substring( lotString.lastIndexOf("$") );
		newLotId += updatedLotId;
		newLotId += "$";
		newLotId += updatedNewLotNumber;
		newLotId += newId;
		return newLotId;
	}


}